package com.ruoyi.common.utils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;

/**
 * 图片添加噪点
 */
public class ImageNoiseProcessor {
    private static final Random random = new Random();
    private static final String[] IMAGE_EXT = {"jpg", "jpeg", "png", "bmp"};

    public static void main(String[] args) {
        String inputPath = "C:\\Users\\lenovo\\Desktop\\0-异常数据原图(3)\\0-异常数据原图";
        String outputPath = "C:\\Users\\lenovo\\Desktop\\0-异常数据原图(3)\\噪点";
        processDirectory(new File(inputPath), new File(outputPath));
    }

    // 递归处理目录（保持文件夹结构）
    private static void processDirectory(File inputDir, File outputDir) {
        if (!outputDir.exists() && !outputDir.mkdirs()) {
            System.err.println("⚠️ 目录创建失败: " + outputDir.getAbsolutePath());
            return;
        }

        File[] files = inputDir.listFiles();
        if (files == null) return;

        for (File file : files) {
            if (file.isDirectory()) {
                File newOutput = new File(outputDir, file.getName());
                processDirectory(file, newOutput); // 递归处理子目录
            } else if (isImageFile(file)) {
                processImage(file, outputDir);
            }
        }
    }

    // 判断是否为图片文件
    private static boolean isImageFile(File file) {
        String name = file.getName().toLowerCase();
        for (String ext : IMAGE_EXT) {
            if (name.endsWith("." + ext)) return true;
        }
        return false;
    }

    // 核心处理逻辑
    private static void processImage(File inputFile, File outputDir) {
        try {
            BufferedImage image = ImageIO.read(inputFile);
            if (image == null) {
                System.err.println("🚨 无法读取图像: " + inputFile);
                return;
            }

            // 生成随机噪声强度（0.5 - 2.0）
            double noiseLevel = 0.5 + random.nextDouble() * 1.9;
            addNoise(image, noiseLevel);

            // 构建输出文件名
            String newName = buildOutputName(inputFile, noiseLevel);
            File outputFile = new File(outputDir, newName);

            // 保持原图片格式
            String format = getFileExtension(inputFile);
            ImageIO.write(image, format, outputFile);

            // 记录处理日志
            System.out.printf("✅ 处理完成: %s → %s (噪声强度: %.2f)\n",
                    inputFile.getName(), outputFile.getName(), noiseLevel);
        } catch (IOException e) {
            System.err.println("❌ 处理失败: " + inputFile + " - " + e.getMessage());
        }
    }

    // 添加噪声（核心算法）
    private static void addNoise(BufferedImage img, double intensity) {
        int width = img.getWidth();
        int height = img.getHeight();

        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int rgb = img.getRGB(x, y);

                // 分解RGB通道
                int r = (rgb >> 16) & 0xFF;
                int g = (rgb >> 8) & 0xFF;
                int b = rgb & 0xFF;

                // 添加随机噪声
                r = addChannelNoise(r, intensity);
                g = addChannelNoise(g, intensity);
                b = addChannelNoise(b, intensity);

                // 重新组合RGB值
                int newRgb = (r << 16) | (g << 8) | b;
                img.setRGB(x, y, newRgb);
            }
        }
    }

    // 单通道噪声处理
    private static int addChannelNoise(int channel, double intensity) {
        // 随机噪声值（-intensity到+intensity）
        double noise = (random.nextDouble() * 2 - 1) * intensity * 255;
        return clamp((int) (channel + noise));
    }

    // 数值边界控制
    private static int clamp(int value) {
        return Math.max(0, Math.min(255, value));
    }

    // 构建输出文件名
    private static String buildOutputName(File file, double noiseLevel) {
        String name = file.getName();
        int dotIndex = name.lastIndexOf('.');
        String baseName = (dotIndex == -1) ? name : name.substring(0, dotIndex);
        String ext = (dotIndex == -1) ? "" : name.substring(dotIndex + 1);
        return String.format("%s_NOISE_%.2f.%s", baseName, noiseLevel, ext);
    }

    // 获取文件扩展名
    private static String getFileExtension(File file) {
        String name = file.getName();
        int dotIndex = name.lastIndexOf('.');
        return (dotIndex == -1) ? "jpg" : name.substring(dotIndex + 1);
    }
}
